BOARD ?= plus-f3270
BOARD_DIR ?= boards/$(BOARD)
BUILD ?= build-$(BOARD)

CROSS_COMPILE ?= arm-none-eabi-

ifeq ($(wildcard $(BOARD_DIR)/.),)
$(error Invalid BOARD specified: $(BOARD_DIR))
endif

include ../../py/mkenv.mk
include $(BOARD_DIR)/mpconfigboard.mk

# qstr definitions (must come before including py.mk)
QSTR_DEFS = qstrdefsport.h
QSTR_GLOBAL_DEPENDENCIES = $(BOARD_DIR)/mpconfigboard.h

# include py core make definitions
include $(TOP)/py/py.mk

MCU_DIR = lib/mm32mcu/$(MCU_SERIES)

# includepath.
INC += -I.
INC += -I$(TOP)
INC += -I$(BUILD)
INC += -I$(BOARD_DIR)
INC += -I$(TOP)/lib/cmsis/inc
INC += -I$(TOP)/$(MCU_DIR)/devices/$(CMSIS_MCU)
INC += -I$(TOP)/$(MCU_DIR)/drivers
INC += -I$(TOP)/lib/rbuf

# flags.
CFLAGS = $(INC)
CFLAGS +=  -Wall -Werror
CFLAGS += -std=c99
CFLAGS += -nostdlib
CFLAGS += -mthumb
CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES))
CFLAGS += -fsingle-precision-constant -Wdouble-promotion
CFLAGS += -D__STARTUP_CLEAR_BSS
CFLAGS += $(CFLAGS_MOD)

CFLAGS_MCU_CM7  = -mtune=cortex-m7 -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16
CFLAGS_MCU_CM4  = -mtune=cortex-m4 -mcpu-cortex-m4 -msoft-float
CFLAGS_MCU_CM3  = -mtune=cortex-m3 -mcpu=cortex-m3 -msoft-float
CFLAGS_MCU_CM0P = -mtune=cortex-m0plus -mcpu=cortex-m0plus -msoft-float

ifeq ($(MCU_SERIES), mm32f3270)
CFLAGS += $(CFLAGS_MCU_CM3)
else
CFLAGS += $(CFLAGS_MCU_CM0P)
endif

CFLAGS += -DMCU_$(MCU_SERIES) -D__$(CMSIS_MCU)__
LDFLAGS = -nostdlib $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref
LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)

# Tune for Debugging or Optimization
ifeq ($(DEBUG),1)
CFLAGS += -O0 -ggdb
else
CFLAGS += -Os -DNDEBUG
LDFLAGS += --gc-sections # remove the unused segment when linking.
CFLAGS += -fdata-sections -ffunction-sections # remove the unused segment when linking.
endif

# source files.
SRC_HAL_C += \
	$(MCU_DIR)/devices/$(CMSIS_MCU)/system_$(CMSIS_MCU).c \
	$(MCU_DIR)/drivers/hal_rcc.c \
	$(MCU_DIR)/drivers/hal_gpio.c \
	$(MCU_DIR)/drivers/hal_uart.c \
	$(MCU_DIR)/drivers/hal_sdio.c \
	$(MCU_DIR)/drivers/hal_dac.c \
	$(MCU_DIR)/drivers/hal_adc.c \
	$(MCU_DIR)/drivers/hal_spi.c \
	$(MCU_DIR)/drivers/hal_i2c.c \
	$(MCU_DIR)/drivers/hal_tim_16b.c \
	$(MCU_DIR)/drivers/hal_tim_basic.c \
	$(MCU_DIR)/drivers/hal_tim_adv.c \


SRC_BRD_C += \
	$(BOARD_DIR)/clock_init.c \
	$(BOARD_DIR)/pin_init.c \
	$(BOARD_DIR)/board_init.c \
	$(BOARD_DIR)/machine_pin_board_pins.c \
	$(BOARD_DIR)/sdcard_sdio.c \


# to enable floating point number and math, with no double FPU, only for single point FPU.
SRC_LIBM_C += $(addprefix lib/libm/,\
	math.c \
	acoshf.c \
	asinfacosf.c \
	asinhf.c \
	atan2f.c \
	atanf.c \
	atanhf.c \
	ef_rem_pio2.c \
	erf_lgamma.c \
	fmodf.c \
	kf_cos.c \
	kf_rem_pio2.c \
	kf_sin.c \
	kf_tan.c \
	log1pf.c \
	nearbyintf.c \
	roundf.c \
	sf_cos.c \
	sf_erf.c \
	sf_frexp.c \
	sf_ldexp.c \
	sf_modf.c \
	sf_sin.c \
	sf_tan.c \
	wf_lgamma.c \
	wf_tgamma.c \
	ef_sqrt.c \
	)

# only enable floating point number without math.
# SRC_LIBM_C += $(addprefix lib/libm/,\
# 	math.c \
# 	fmodf.c \
# 	nearbyintf.c \
# 	ef_sqrt.c \
# 	)

# SRC_LIBM_C += lib/libm/ef_sqrt.c # for single ponit with no hardware fpu.

SRC_DRIVERS_C += $(addprefix drivers/,\
	bus/softspi.c \
	)



SRC_C += \
	main.c \
	modmachine.c \
	modutime.c \
	moduos.c \
	machine_pin.c \
	machine_sdcard.c \
	machine_uart.c \
	machine_dac.c \
	machine_adc.c \
	machine_spi.c \
	machine_i2c.c \
	machine_pwm.c \
	machine_timer.c \
	mphalport.c \
	lib/libc/string0.c \
	lib/mp-readline/readline.c \
	lib/utils/gchelper_native.c \
	lib/utils/printf.c \
	lib/utils/pyexec.c \
	lib/utils/stdout_helpers.c \
	lib/rbuf/rbuf.c \
	lib/timeutils/timeutils.c \
	fatfs_port.c \
	$(SRC_HAL_C) \
	$(SRC_BRD_C) \
	$(SRC_MOD) \
	$(SRC_LIBM_C) \
	$(SRC_DRIVERS_C) \


# also use cm3 as gchelper_m3.s
ifeq ($(MCU_SERIES), mm32f3270)
SRC_S = lib/utils/gchelper_m3.s
else
SRC_S = lib/utils/gchelper_m0.s
endif

SRC_SS = $(MCU_DIR)/devices/$(CMSIS_MCU)/startup_$(CMSIS_MCU).S

# list of sources for qstr extraction
SRC_QSTR += modmachine.c \
			modutime.c \
			moduos.c \
			machine_pin.c \
			machine_sdcard.c \
			machine_uart.c \
			machine_dac.c \
			machine_adc.c \
			machine_spi.c \
			machine_i2c.c \
			machine_pwm.c \
			machine_timer.c \
			$(BOARD_DIR)/machine_pin_board_pins.c \

# output obj file.
OBJ += $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_SS:.S=.o))

# rules.
all: $(BUILD)/firmware.bin

$(BUILD)/firmware.elf: $(OBJ)
	$(ECHO) "LINK $@"
	$(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
	$(Q)$(SIZE) $@

$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
	$(Q)$(OBJCOPY) -O binary $^ $@

$(BUILD)/firmware.hex: $(BUILD)/firmware.elf
	$(Q)$(OBJCOPY) -O ihex -R .eeprom $< $@


include $(TOP)/py/mkrules.mk
